#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    ifstream ifs;
    filebuf* buf = ifs.rdbuf();
    if (buf->open("test.txt", ios::out) == nullptr)
    {
        cerr << "open failed" << endl;
        buf->close();
        return -1;
    }
    ostream os(buf);
    // 文本串可能立即打印出来，也可能被操作系统保存在缓冲区中，随后再打印
    os << "please enter a value: ";

    /**
     * 导致缓冲刷新（即，数据真正写到输出设备或文件）的原因：
     * 1. 程序正常结束
     * 2. 缓冲区满
     * 3. 使用操作符（如 endl）来显式刷新缓冲区
     * 4. 使用操作符（如 unitbuf）设置流的内部状态，来清空缓冲区
     * 5. 一个输出流被关联到另一个流，当读写被关联的流时，关联到的流的缓冲区会被刷新
     */

    cout << "hi!" << endl;  // 输出 hi 和一个换行，然后刷新缓冲区
    cout << "hi!" << flush; // 输出 hi，然后刷新缓冲区，不附加任何额外字符
    cout << "hi!" << ends;  // 输出 hi 和一个空字符，然后刷新缓冲区

    cout << unitbuf;        // 所有输出操作后都会立即刷新缓冲区
    // 任何输出都立即刷新，无缓冲
    cout << nounitbuf;      // 回到正常的系统管理的缓冲区刷新机制

    int ival;
    // 标准库默认将 cout 和 cin 关联在一起
    // cin.tie(&cout);
    cin >> ival;            // cout 的缓冲区被刷新

    // old_tie 指向当前关联到 cin 的流（如果有的话）
    ostream *old_tie = cin.tie(nullptr); // cin 不再与其他流关联
    // 将 cin 与 cerr 关联；这不是一个好主意，因为 cin 应该关联到 cout
    cin.tie(&cerr);         // 读取 cin 会刷新 cerr 而不是 cout
    cin.tie(old_tie);       // 重建 cin 和 cout 间的正常关联
}